package com.voole.security.support;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;

import com.voole.service.ISysUserService;

/**
 * 用户请求URL 校验类
 * 
 * resourceMap 记录 整个web应用 的 所有 <请求URL、权限>
 * 这里只校验，用户的请求是否在web应用中存在，
 * 它通过后，会调用CustomAccessDecisionManager.decide()
 */

@Service
public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
	
	@Autowired
	private ISysUserService sysUserService;
	
	private Map<String, Collection<ConfigAttribute>> resourceMap = null;
	
	//tomcat启动时实例化一次
	public CustomSecurityMetadataSource() {
		//loadResourceDefine();  
	}
	
	//tomcat开启时加载一次，加载所有url和权限（或角色）的对应关系，如果启动tomcat后有变更，这里就是脏数据
	private void loadResourceDefine() {
		//以下是举例，并不实际应用，可以换成从数据库取出并遍历存入resourceMap
		resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); 
		
		Collection<ConfigAttribute> atts1 = new ArrayList<ConfigAttribute>(); 
		ConfigAttribute ca1 = new SecurityConfig("ROLE_USER");
		atts1.add(ca1); 
		resourceMap.put("/index.jsp", atts1);
		
		Collection<ConfigAttribute> atts2 = new ArrayList<ConfigAttribute>(); 
		ConfigAttribute ca2 = new SecurityConfig("ROLE_NO");
		atts2.add(ca2);
		resourceMap.put("/http://contented.blog.sohu.com", atts2);   
	}  
	
	//参数是要访问的url，返回这个url对于的所有权限（或角色）
	public Collection getAttributes(Object object) throws IllegalArgumentException { 
		// 将参数转为 url    
		String requestURL = ((FilterInvocation)object).getRequestUrl();
		if (requestURL.indexOf("?") != -1){
			requestURL = requestURL.substring(0, requestURL.indexOf("?"));
		}
		//从数据库获取 web程序 所有URL 和 对应权限
		try {
			resourceMap = sysUserService.getResourceMap();
		} catch (Exception e) {
			e.printStackTrace();
			throw new IllegalArgumentException("没有权限访问!");
		}
		
		Collection<ConfigAttribute> c = resourceMap.get(requestURL);//根据用户请求URL，取得需要具备的 权限集合，只要满足集合中的一个即可。
		if (c == null) {
			//throw new IllegalArgumentException("没有权限访问!");//首次登陆会先进index.do，这里抛异常无法进入登陆页面
		}
		return c;   
	}
	
	public boolean supports(Class<? > clazz) {
		//这里必须是ture，否则启动会报does not support secure object class:class org.springframework.security.web.FilterInvocation
		return true;
	}
	
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

}